# -*- coding: utf-8 -*-
import os, sys, logging
# Add parent folder to sys.path, so we can import boot.
# App Engine causes main.py to be reloaded if an exception gets raised
# on the first request of a main.py instance, so don't add parent_dir multiple
# times.
parent_dir = os.path.abspath(os.path.dirname(__file__))
logging.info('parent_dir: %s' % parent_dir)
if parent_dir not in sys.path:
    sys.path.insert(0, parent_dir)

# Google App Engine imports.
from google.appengine.ext.webapp import util
from google.appengine.api import xmpp
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import memcache

# Remove the standard version of Django
if 'django' in sys.modules and sys.modules['django'].VERSION < (1, 2):
    for k in [k for k in sys.modules
              if k.startswith('django\.') or k == 'django']:
        del sys.modules[k]

from djangoappengine import boot
from django.http import HttpResponseRedirect


boot.setup_threading()
boot.setup_project()
boot.setup_logging()
boot.setup_env()

import django.core.handlers.wsgi
from django.conf import settings
os.environ.update(boot.env_ext)
from waveapi import robot
from waveapi import appengine_robot_runner
from djapp import models as djapp_models
import passwords, re

class TagRenaming:
    def __init__(self):
        pass


class XMPPHandler(webapp.RequestHandler):
    RENAME_TAG = u'rename'
    ADDUSERTOWAVE_TAG = u'addusertowave'
    ACCESS_ERROR = u"Недостаточно прав для выполнения операции."
    HELP_TEXT = u"Команда должна быть в формате (кавычки обязательны): \
                                    rename \"старый тег\" \"новый тег\""
                                    

    def add_user(self, user, wave_id):
        myRobot = robot.Robot(passwords.ROBOT_NAME,
            image_url = passwords.IMAGE_URL,
            profile_url = passwords.PROFILE_URL)
        myRobot.setup_oauth(passwords.CONSUMER_KEY, passwords.CONSUMER_SECRET, \
                server_rpc_base='http://www-opensocial.googleusercontent.com/api/rpc')
        appengine_robot_runner.run(myRobot)
        db_controller = memcache.get("db_controller")
        try:
            wave = myRobot.fetch_wavelet(wave_id = wave_id)
            wave.participants.add(user)
            myRobot.submit(wave)
            message = u"Пользователь \"%s\" успешно добавлен в волну \"%s\"" % (user, wave_id)
        except RpcError:
            message = u"Робот не является участником волны."
        except:
            logging.error('Could not add user.', exc_info=True)
            message = u'Произошла ошибка.'
        return message
   
    def rename_tag(self, old_tag, new_tag):
        """
        Case-nonsensetive renaming
        """
        r = robot.Robot(passwords.ROBOT_NAME,
        image_url = passwords.IMAGE_URL,
        profile_url = passwords.PROFILE_URL)
        r.setup_oauth(passwords.CONSUMER_KEY, passwords.CONSUMER_SECRET, 
                      server_rpc_base='http://www-opensocial.googleusercontent.com/api/rpc')
        appengine_robot_runner.run(r)
        wave_list = djapp_models.Wave.objects.all()
        count = 0
        error = 0      
        old_tag = old_tag.lower()  
        for w in wave_list:
            if w.tags:
                dbwave_tags = map(lambda x: x.lower(), w.tags) #get lower tags
                if old_tag in dbwave_tags:
                    try:
                        edited_wave = r.fetch_wavelet(wave_id = w.wave_id)
                        wave_tags = edited_wave.tags.serialize()
                        delete_tags = filter(lambda x: x.lower() == old_tag, wave_tags) #filter delete tags
                        w.tags = filter(lambda x: x != old_tag, [t.lower() for t in wave_tags]) #sync with gw
                        w.title = edited_wave.title or '<no title>'
                        for tag in delete_tags:
                            edited_wave.tags.remove(tag)
                        edited_wave.tags.append(new_tag)
                        r.submit(edited_wave)
                        w.tags.append(new_tag.lower())
                        w.save()
                        count += 1
                    except:
                        logging.error('Could not change tag.', exc_info=True)
                        error += 1
        if not memcache.add("has_changes", True):
            memcache.set("has_changes", True)                    
        return count, error
    
    def post(self):
        message = xmpp.Message(self.request.POST)
        logging.warning(self.request.POST)
        c = None
        try:
            c = djapp_models.TagEditor.objects.get(email = message.sender.split('/')[0])
        except djapp_models.TagEditor.DoesNotExist:
            pass
        except djapp_models.TagEditor.MultipleObjectsReturned:
            pass
        if c:            
            command = message.body.split("\"")
            command = filter(lambda x: x, map(unicode.strip, command))
            logging.warning("%s: %s" % (message.body, command))
            
            #rename tag
            if command[0] == XMPPHandler.RENAME_TAG: 
                if len(command) < 3 or command[1] == command[2]:
                    message.reply(XMPPHandler.HELP_TEXT)
                    return
                if command[0] == XMPPHandler.RENAME_TAG:
                    count, error = self.rename_tag(command[1], command[2])
                    message.reply(u"Переименование тега \"%s\" в тег \"%s\": \
                                  успешно переименовано - %d, неуспешно переименовано - %d" % \
                                  (command[1], command[2], count, error))
            #add to wave
            elif command[0] == XMPPHandler.ADDUSERTOWAVE_TAG:
                if len(command) == 2:
                    if not self.wave_id_validation(command[1]):
                        message.reply(u'WaveID должен быть в формате "\googlewave.com!w+XXXXXXXXX\"')
                        return
                    sender = message.sender.split('/')[0].split('@')[0]
                    sender += '@googlewave.com'
                    msg = self.add_user(sender, command[1])
                    message.reply(msg)
                elif len(command) == 3:
                    if not self.wave_id_validation(command[2]):
                        message.reply(u'WaveID должен быть в формате "\googlewave.com!w+XXXXXXXXX\"')
                        return
                    msg = self.add_user(command[1], command[2])
                    message.reply(msg)
        else:
            message.reply(XMPPHandler.ACCESS_ERROR)
            
    def wave_id_validation(self, wave_id): #/w+6juI-EdvC 
        w = wave_id.split('!')
        if w[0] != 'googlewave.com':
            return False  
        return True


application = webapp.WSGIApplication([('/_ah/xmpp/message/chat/', XMPPHandler)],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()